package org.jeecg.modules.cascv.image.service.merge;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.HexUtil;
import com.NativeImageIO;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.config.TaskExecutePool;
import org.jeecg.modules.cascv.image.util.HeaderUtil;
import org.jeecg.modules.cascv.image.util.LaptopConstant;
import org.jeecg.modules.cascv.image.util.LaptopUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicInteger;

@Service
@Slf4j
public class WurongqiService extends ImageService {
    @Value("${imageurl}")
    private  String imageurl;
    @Autowired
    private TaskExecutePool taskExecutePool;

    private AtomicInteger num = new AtomicInteger(0);

    @Override
    public String idsNames() {//设备的文件格式描述文件，每个设备吐出来的数据格式 ids格式文件 接口数据

        return "TGTHYY0401_090H_31_CMPRAPP5,TGTHYY0401_090H_31_CMPRAPP6,TGTHYY0401_090H_31_CMPRAPP7,6D5DH_3CH,6D6DH_3BH,6D7DH_3CH";
    }


    public Result<Object> merge(JSONObject jsonObject, String idsName, String key) {
        JSONObject conJson = jsonObject.getJSONObject("Content");


        //打印报错不连续的包序号
        String packageNum = conJson.getString(LaptopConstant.Package_number_MAP.get(idsName));
        int intpackageNum = Integer.parseInt(packageNum.split(";")[1]);
        Integer lastPackageNum = LaptopConstant.packageNumMap.get(key);

        if(null==lastPackageNum){
            LaptopConstant.packageNumMap.put(key,intpackageNum);
        }else {
            LaptopConstant.packageNumMap.put(key,intpackageNum);
            if (lastPackageNum + 1 != intpackageNum) {
                if (2511 != lastPackageNum && 0 != intpackageNum) {
                    log.error("图像丢包，包序号不连续，当前包的包序号:"+intpackageNum+"，上一包包序号:"+lastPackageNum);
                }
            }
        }

        String secondStr = jsonObject.getString("second");
        long second = Long.parseLong(secondStr);
        String subSecondStr = jsonObject.getString("subsecond");
        secondStr = LaptopUtil.toDayHoursMinSec(second);
        String frames_field = LaptopConstant.FRAME_FIELD_MAP.get(idsName);
        String dataFrames = conJson.getString(frames_field);
        conJson.remove(frames_field);
        //dataFrames = dataFrames.substring(7,dataFrames.length()-10);
        dataFrames= dataFrames.split(";")[1];
        dataFrames = dataFrames.substring(2).trim();
        StringBuilder queue = LaptopConstant.imageData.get(key);
        if (queue != null && queue.length() < 2006 * 2) { //ququ不是空切长度不小于2006*2
            dataFrames = queue.toString() + dataFrames;
            boolean checkStart = false;
            if (StringUtils.containsIgnoreCase(dataFrames, LaptopConstant.WURONGQI_HEADER)) { //表示是否包含1acffc1d

                checkStart = true;
            }

            if (checkStart) { //如果为true
                queue = new StringBuilder();//new一个queue存入imageData
                LaptopConstant.imageData.put(key, queue);
                queue.append(dataFrames); //queue添加dataFrames

            } else {//如果是假的 那么将这个key删除掉  dataFrams不包含"1acffc1d"
                LaptopConstant.imageData.remove(key);
            }
            return null;
        }
//判断是否包含WURONGQI_HEADER = "1acffc1d"
        if (StringUtils.containsIgnoreCase(dataFrames, LaptopConstant.WURONGQI_HEADER)) {
            if (queue != null) { //queue有数据
                queue.append(dataFrames); //queue加上dataFrames
                if (queue.length() > 2006 * 2) { //如果queue的长度是大于2006*2的 那么去合并
                    composite(queue, conJson, idsName, key,secondStr,subSecondStr);
                }
            }
            //创建一个queue
            queue = new StringBuilder();
            //存入imageData
            LaptopConstant.imageData.put(key, queue);
            //queue再添加dataFrames  dataFrames:是已被queue加上的之后的了  dataFrames = queue.toString() + dataFrames;


            queue.append(dataFrames); //然后把刚才new的queue再加上dataFrames

            return null;
        }

        if (isNeedMergeBehindXuanFu(dataFrames) && queue == null) {//判断dataFrames是否有结尾，并且queue不是空的
            queue = new StringBuilder();
            LaptopConstant.imageData.put(key, queue);
            //Java中的append( )方法其实是创建了一个新的数组，扩大了长度，将需要添加的字符串给复制到这个新的数组中
            //Stringbuffer是动态字符串数组，append( )是往动态字符串数组添加，跟“xxxx”+“yyyy”相当‘+’号
            queue.append(dataFrames);

            return null;
        } else if (queue != null) { //如果queue不是空的那么加上dataFrames

            queue.append(dataFrames);
            return null;
        }

        return null;
    }


    private  boolean composite(StringBuilder sb, JSONObject content, String idsName, String key,String secondStr,String subSecondStr) {
       // log.info("composite");

        boolean removeHeader = false;
        boolean removePre = false;
        //查找WURONGQI_HEADER = "1acffc1d"第一次出现的位置  headerIndex：1acffc1d的位置
        int headerIndex = StringUtils.indexOfIgnoreCase(sb.toString(), LaptopConstant.WURONGQI_HEADER);
        // System.out.println("headerIndex = " + headerIndex);
        //WURONGQI_HEADER = "1acffc1d";
        //截取 headerIndex+8到headerIndex+88的 生成header44Str
        String header44Str = sb.substring(headerIndex + 8, headerIndex + 88);
       // System.out.println("header44Str = " + header44Str);
        int width = Integer.parseInt(header44Str.substring(48, 56), 16); //截取header44Str的 48-56 然后转换成16进制
        int height = Integer.parseInt(header44Str.substring(56, 64), 16);
        int imageSize = width * height; //图像尺寸
        sb.delete(0, headerIndex); //删除0到头部位置

        String headerStr = sb.substring(0, 96); //截取0-96
        //    Map<String, String> headerMap = HeaderUtil.parseGaowengui(headerStr);
        sb = sb.delete(0, 96); //在删除0-96

        int oneCanSize = 16 + 1464 * 2;

        int headerSize = 16;//标头大小

        ByteBuffer byteBuf = ByteBuffer.allocate(imageSize); //分配缓冲区
        int writeIndex = 0;

        int i = 0;

        while (true) {
            if (sb.length() < oneCanSize) {
                break;
            }
            String oneCanStr = sb.substring(0, oneCanSize).trim();
            if (oneCanStr.length() < oneCanSize) {
                break;
            }
            //拿到oneCanStr后，将其从sb中删除
            sb.delete(0, oneCanSize);
            byte[] bytes = new byte[0];
            try {
                bytes = HexUtil.decodeHex(oneCanStr.substring(headerSize));
            } catch (Exception e) {
                e.printStackTrace();
            }
            int writeLen = bytes.length;
            if (writeIndex + writeLen > imageSize) {
                writeLen = imageSize - writeIndex;
                byteBuf.put(ArrayUtil.sub(bytes, 0, writeLen));
            } else {
                byteBuf.put(bytes);
            }
            writeIndex += writeLen;
            if (writeIndex > imageSize) {
                break;
            }
        }

        if (writeIndex < imageSize && sb.length() / 2 > imageSize - writeIndex) {
            String oneCanStr = null;
            try {
                oneCanStr = sb.substring(headerSize, (imageSize - writeIndex) * 2 + headerSize);
                byte[] bytes = HexUtil.decodeHex(oneCanStr);
                byteBuf.put(bytes);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        CompletableFuture<JSONObject> future = CompletableFuture.supplyAsync(() -> {
            long start = System.currentTimeMillis();

            //  log.info("开始合成图片");
            //    System.out.println(byteBuf.position() + ",,, " + imageSize);
                if (byteBuf.position() < imageSize) {
                    byte[] arr = new byte[imageSize - byteBuf.position()];
                    Arrays.fill(arr, (byte) 0); //要填充的数组
                    byteBuf.put(arr);
                }

//        合成成功ImageTask(id=41560151012334,15453, framesType=1, packageTotalNum=19, headerIndex=1316, totalLength=37136, needMergeType=2, startId=41560151012334,15453, endId=41560151012414,15471, startEndFlag=1, idsName=TGTHYY0401_090H_31_CMPRAPP5, pgTy=cg, dataType=null, delFlag=0, width=192, height=192, planTime=1668577360137, dcNo=SD00, taskNo=22111611, retry=1, cost=0, costStart=1668577363724, iocost=58, createTime=1668577363672, imageNo=null, taskType=1, forceCreateImage=0, secondKey=null, zdyMap={A1_CMPR_MICU_APP5DATA_ZDY_1=0000b2eaH;45802;图像帧数;否, A1_CMPR_MICU_APP5DATA_ZDY_2=01H;01H;标识;否, A1_CMPR_MICU_APP5DATA_ZDY_3=0000000000H;0000000000H;填充;否, A1_CMPR_MICU_APP5DATA_ZDY_4=0001H;0001H;载荷类型;否, A1_CMPR_MICU_APP5DATA_ZDY_10=00000088H;136;y偏移;否, A1_CMPR_MICU_APP5DATA_ZDY_5=0000009d757547e4H;5410243886880;时间戳;否, A1_CMPR_MICU_APP5DATA_ZDY_6=01080001H;01080001H;图片格式;否, A1_CMPR_MICU_APP5DATA_ZDY_7=000000c0H;192;宽;否, A1_CMPR_MICU_APP5DATA_ZDY_8=000000c0H;192;高;否, A1_CMPR_MICU_APP5DATA_ZDY_9=000000e0H;224;x偏移;否, A1_CMPR_MICU_APP5DATA_ZDY_12=0000H;0;Padding-y;否, A1_CMPR_MICU_APP5DATA_ZDY_11=0000H;0;Padding-x;否}, imageType=null, wei_sheng=0, imgModel=null, firstNo=null, offSet=null, stepNos=null, imgNum=null, packageNo=null)
//        合成成功ImageTask(id=41560151012254,15434, framesType=1, packageTotalNum=20, headerIndex=3272, totalLength=37136, needMergeType=2, startId=41560151012254,15434, endId=41560151012334,15453, startEndFlag=1, idsName=TGTHYY0401_090H_31_CMPRAPP5, pgTy=cg, dataType=null, delFlag=0, width=192, height=192, planTime=1668577360137, dcNo=SD00, taskNo=22111611, retry=1, cost=0, costStart=1668577363724, iocost=62, createTime=1668577363653, imageNo=null, taskType=1, forceCreateImage=0, secondKey=null, zdyMap={A1_CMPR_MICU_APP5DATA_ZDY_1=0000b2e9H;45801;图像帧数;否, A1_CMPR_MICU_APP5DATA_ZDY_2=01H;01H;标识;否, A1_CMPR_MICU_APP5DATA_ZDY_3=0000000000H;0000000000H;填充;否, A1_CMPR_MICU_APP5DATA_ZDY_4=0001H;0001H;载荷类型;否, A1_CMPR_MICU_APP5DATA_ZDY_10=00000088H;136;y偏移;否, A1_CMPR_MICU_APP5DATA_ZDY_5=0000009d75708314H;5410241386656;时间戳;否, A1_CMPR_MICU_APP5DATA_ZDY_6=01080001H;01080001H;图片格式;否, A1_CMPR_MICU_APP5DATA_ZDY_7=000000c0H;192;宽;否, A1_CMPR_MICU_APP5DATA_ZDY_8=000000c0H;192;高;否, A1_CMPR_MICU_APP5DATA_ZDY_9=000000e0H;224;x偏移;否, A1_CMPR_MICU_APP5DATA_ZDY_12=0000H;0;Padding-y;否, A1_CMPR_MICU_APP5DATA_ZDY_11=0000H;0;Padding-x;否}, imageType=null, wei_sheng=0, imgModel=null, firstNo=null, offSet=null, stepNos=null, imgNum=null, packageNo=null)

                byteBuf.flip();
                byte[] arr = new byte[imageSize];
                if (byteBuf.limit() < imageSize) {
                    System.out.println("长度不足");
                }
                byteBuf.get(arr);
               // System.out.println("arr = " + arr.length);
                String idStr = IdWorker.getIdStr();
                idStr = idStr+".png";
                int png = LaptopConstant.nativeImageIO.write(arr,height,width, "/data/images/", idStr, "png");
                String imageUrl = "http://" + imageurl + "/jeecg-boot/test/gmvVideo/getImage/" + idStr;

              //  log.info("succes");


                content.put("imageUrl", imageUrl);
                content.put("idsName", idsName);

                String[] split = secondStr.split(":");
                content.put("ts", split[0] + "天" + split[1] + "时" + split[2] + "分" + split[3] + "秒" + subSecondStr + "微秒");
                content.remove(LaptopConstant.FRAME_FIELD_MAP.get(idsName));

            content.put("key", key);
            log.info("无容器"+idsName+"合成一张图片消耗时间：" + (System.currentTimeMillis() - start) + "毫秒");

            return content;
        },taskExecutePool.threadPoolTaskExecutor2());
        LaptopConstant.imageFutureList.add(future);

        return true;
    }

    private boolean isNeedMergeBehindXuanFu(String dataFrames) {


        return  StringUtils.endsWithIgnoreCase(dataFrames,LaptopConstant.WURONGQI_HEADER_START_SUB_1)//后缀均可以通过endsWith()方法来判断 是的返回true
                ||  StringUtils.endsWithIgnoreCase(dataFrames,LaptopConstant.WURONGQI_HEADER_START_SUB_2)
                ||  StringUtils.endsWithIgnoreCase(dataFrames,LaptopConstant.WURONGQI_HEADER_START_SUB_3)
                ;

    }

    public static void main(String[] args) {
        System.load("D:/disk1/libjpeg-9.dll");
        System.load("D:/disk1/libpng-3.dll");
        System.load("D:/disk1/NativeImageIOJNI.dll"); //D:\图像数据\无容器   D:\pc_workspace\wurongqi2
        List<String> strings = FileUtil.readUtf8Lines("E:\\图像数据\\cut\\无容器\\T20230407111119_0001_0090_F1_00_6DCD_2024_003B_3B_6D6D_000000000.txt");
        WurongqiService test = new WurongqiService();
        for (String string : strings) {
            //将str转化为相应的JSONObject对象
            JSONObject jsonObject = JSONObject.parseObject(string);
            test.merge(jsonObject, "6D6DH_3BH", "6D6DH_3BH");
        }

    }
}
